/**
 * 恢复引擎使用示例
 * 演示如何使用恢复引擎进行文件恢复操作
 */

import { RecoveryEngineImpl } from '../recovery-engine'
import { FileOperationsImpl } from '../file-operations'
import type {
  HistoryParser,
  RecoveryOptions,
  RecoveryTask,
  BatchRecoveryOptions
} from '../../types'

// 模拟历史解析器（在实际使用中应该使用真实的实现）
class MockHistoryParser implements HistoryParser {
  private mockFiles = new Map<string, Map<string, string>>([
    ['version-1', new Map([
      ['App.vue', '<template><div>App Version 1</div></template>'],
      ['main.ts', 'import { createApp } from "vue"\nconsole.log("Version 1")'],
      ['utils.ts', 'export function helper() { return "v1" }']
    ])],
    ['version-2', new Map([
      ['App.vue', '<template><div>App Version 2</div></template>'],
      ['main.ts', 'import { createApp } from "vue"\nconsole.log("Version 2")'],
      ['components/Button.vue', '<template><button>Click me</button></template>']
    ])]
  ])

  async scanHistoryVersions() {
    return [
      { id: 'version-1', timestamp: Date.now() - 86400000, fileCount: 3, hasEntriesFile: true },
      { id: 'version-2', timestamp: Date.now() - 43200000, fileCount: 3, hasEntriesFile: true }
    ]
  }

  async parseVersionEntries(versionId: string) {
    return {
      version: 1,
      resource: 'project',
      entries: Array.from(this.mockFiles.get(versionId)?.keys() || []).map(fileId => ({
        id: fileId,
        timestamp: Date.now()
      }))
    }
  }

  async getFileHistory(filePath: string) {
    return []
  }

  async getFileContent(versionId: string, fileId: string): Promise<string> {
    const versionFiles = this.mockFiles.get(versionId)
    if (!versionFiles || !versionFiles.has(fileId)) {
      throw new Error(`File ${fileId} not found in version ${versionId}`)
    }
    return versionFiles.get(fileId)!
  }
}

/**
 * 演示单文件恢复
 */
async function demonstrateSingleFileRecovery() {
  console.log('\n=== 单文件恢复演示 ===')
  
  const historyParser = new MockHistoryParser()
  const fileOperations = new FileOperationsImpl()
  const recoveryEngine = new RecoveryEngineImpl(historyParser, fileOperations)

  const options: RecoveryOptions = {
    overwrite: false,
    createDirectories: true,
    preserveTimestamp: false
  }

  try {
    // 恢复 App.vue 文件
    const result = await recoveryEngine.recoverFile(
      'version-1',
      'App.vue',
      './test-temp/recovered/App.vue',
      options
    )

    if (result.success) {
      console.log(`✅ 文件恢复成功: ${result.targetPath}`)
      console.log(`📊 写入字节数: ${result.bytesWritten}`)
    } else {
      console.log(`❌ 文件恢复失败: ${result.error}`)
    }
  } catch (error) {
    console.error('恢复过程中发生错误:', error)
  }
}

/**
 * 演示批量文件恢复
 */
async function demonstrateBatchRecovery() {
  console.log('\n=== 批量文件恢复演示 ===')
  
  const historyParser = new MockHistoryParser()
  const fileOperations = new FileOperationsImpl()
  const recoveryEngine = new RecoveryEngineImpl(historyParser, fileOperations)

  const tasks: RecoveryTask[] = [
    {
      versionId: 'version-1',
      fileId: 'App.vue',
      originalPath: 'src/App.vue',
      targetPath: './test-temp/batch-recovery/App.vue'
    },
    {
      versionId: 'version-1',
      fileId: 'main.ts',
      originalPath: 'src/main.ts',
      targetPath: './test-temp/batch-recovery/main.ts'
    },
    {
      versionId: 'version-1',
      fileId: 'utils.ts',
      originalPath: 'src/utils.ts',
      targetPath: './test-temp/batch-recovery/utils.ts'
    }
  ]

  const options: BatchRecoveryOptions = {
    overwrite: true,
    createDirectories: true,
    preserveTimestamp: false,
    continueOnError: true,
    maxConcurrent: 2
  }

  try {
    console.log(`📦 开始批量恢复 ${tasks.length} 个文件...`)
    
    const result = await recoveryEngine.batchRecover(tasks, options)

    console.log(`✅ 成功恢复: ${result.successful.length} 个文件`)
    console.log(`❌ 恢复失败: ${result.failed.length} 个文件`)
    console.log(`⏱️  总耗时: ${result.duration}ms`)

    // 显示成功恢复的文件
    result.successful.forEach(success => {
      console.log(`  ✓ ${success.targetPath} (${success.bytesWritten} bytes)`)
    })

    // 显示失败的文件
    result.failed.forEach(failure => {
      console.log(`  ✗ ${failure.targetPath}: ${failure.error}`)
    })
  } catch (error) {
    console.error('批量恢复过程中发生错误:', error)
  }
}

/**
 * 演示恢复预览功能
 */
async function demonstrateRecoveryPreview() {
  console.log('\n=== 恢复预览演示 ===')
  
  const historyParser = new MockHistoryParser()
  const fileOperations = new FileOperationsImpl()
  const recoveryEngine = new RecoveryEngineImpl(historyParser, fileOperations)

  const tasks: RecoveryTask[] = [
    {
      versionId: 'version-2',
      fileId: 'App.vue',
      originalPath: 'src/App.vue',
      targetPath: './test-temp/preview/App.vue'
    },
    {
      versionId: 'version-2',
      fileId: 'components/Button.vue',
      originalPath: 'src/components/Button.vue',
      targetPath: './test-temp/preview/components/Button.vue'
    }
  ]

  try {
    // 先创建一个已存在的文件来演示冲突检测
    await fileOperations.ensureDirectory('./test-temp/preview')
    await fileOperations.writeFile('./test-temp/preview/App.vue', 'existing content')

    const preview = await recoveryEngine.previewRecovery(tasks)

    console.log(`📋 预览信息:`)
    console.log(`  📁 待恢复文件数: ${preview.tasks.length}`)
    console.log(`  ⚠️  冲突文件数: ${preview.conflicts.length}`)
    console.log(`  📊 总大小: ${preview.totalSize} bytes`)
    console.log(`  ⏱️  预估耗时: ${preview.estimatedDuration}ms`)

    // 显示冲突详情
    preview.conflicts.forEach(conflict => {
      console.log(`  🔥 冲突: ${conflict.targetPath}`)
      console.log(`    - 文件已存在: ${conflict.existingFile}`)
      console.log(`    - 大小冲突: ${conflict.sizeConflict}`)
    })
  } catch (error) {
    console.error('预览过程中发生错误:', error)
  }
}

/**
 * 演示错误处理
 */
async function demonstrateErrorHandling() {
  console.log('\n=== 错误处理演示 ===')
  
  const historyParser = new MockHistoryParser()
  const fileOperations = new FileOperationsImpl()
  const recoveryEngine = new RecoveryEngineImpl(historyParser, fileOperations)

  const options: RecoveryOptions = {
    overwrite: false,
    createDirectories: true,
    preserveTimestamp: false
  }

  // 演示各种错误情况
  const errorCases = [
    {
      name: '空版本ID',
      versionId: '',
      fileId: 'test.ts',
      targetPath: './test-temp/error/test.ts'
    },
    {
      name: '不存在的文件',
      versionId: 'version-1',
      fileId: 'nonexistent.ts',
      targetPath: './test-temp/error/nonexistent.ts'
    },
    {
      name: '路径遍历攻击',
      versionId: 'version-1',
      fileId: 'App.vue',
      targetPath: '../../../etc/passwd'
    }
  ]

  for (const errorCase of errorCases) {
    try {
      console.log(`🧪 测试: ${errorCase.name}`)
      
      const result = await recoveryEngine.recoverFile(
        errorCase.versionId,
        errorCase.fileId,
        errorCase.targetPath,
        options
      )

      if (result.success) {
        console.log(`  ✅ 意外成功`)
      } else {
        console.log(`  ❌ 预期失败: ${result.error}`)
      }
    } catch (error) {
      console.log(`  💥 抛出异常: ${error instanceof Error ? error.message : String(error)}`)
    }
  }
}

/**
 * 演示并发控制
 */
async function demonstrateConcurrencyControl() {
  console.log('\n=== 并发控制演示 ===')
  
  const historyParser = new MockHistoryParser()
  const fileOperations = new FileOperationsImpl()
  const recoveryEngine = new RecoveryEngineImpl(historyParser, fileOperations)

  // 创建大量任务来测试并发控制
  const tasks: RecoveryTask[] = Array.from({ length: 10 }, (_, i) => ({
    versionId: i % 2 === 0 ? 'version-1' : 'version-2',
    fileId: i % 2 === 0 ? 'App.vue' : 'main.ts',
    originalPath: `src/file${i}.ts`,
    targetPath: `./test-temp/concurrent/file${i}.ts`
  }))

  const options: BatchRecoveryOptions = {
    overwrite: true,
    createDirectories: true,
    preserveTimestamp: false,
    continueOnError: true,
    maxConcurrent: 3 // 限制并发数
  }

  try {
    console.log(`🚀 开始并发恢复 ${tasks.length} 个文件 (最大并发: ${options.maxConcurrent})`)
    
    const startTime = Date.now()
    const result = await recoveryEngine.batchRecover(tasks, options)
    const endTime = Date.now()

    console.log(`⏱️  实际耗时: ${endTime - startTime}ms`)
    console.log(`📊 成功率: ${(result.successful.length / result.totalCount * 100).toFixed(1)}%`)
  } catch (error) {
    console.error('并发恢复过程中发生错误:', error)
  }
}

/**
 * 主演示函数
 */
async function runDemo() {
  console.log('🎯 恢复引擎功能演示')
  console.log('=' .repeat(50))

  try {
    await demonstrateSingleFileRecovery()
    await demonstrateBatchRecovery()
    await demonstrateRecoveryPreview()
    await demonstrateErrorHandling()
    await demonstrateConcurrencyControl()
    
    console.log('\n✨ 演示完成!')
  } catch (error) {
    console.error('演示过程中发生错误:', error)
  }
}

// 如果直接运行此文件，则执行演示
if (import.meta.url === `file://${process.argv[1]}`) {
  runDemo()
}

export {
  demonstrateSingleFileRecovery,
  demonstrateBatchRecovery,
  demonstrateRecoveryPreview,
  demonstrateErrorHandling,
  demonstrateConcurrencyControl,
  runDemo
}